#include "query_result.h"

#include <sstream>
#include <iomanip>

namespace kwdb {

// 匿名命名空间 - 辅助函数
namespace {
    std::map<std::string, std::string> buildNamedValues(const std::vector<std::string>& values,
                                                         const std::vector<std::string>& columns) {
        std::map<std::string, std::string> namedValues;
        size_t minSize = std::min(values.size(), columns.size());
        
        for (size_t i = 0; i < minSize; ++i) {
            namedValues[columns[i]] = values[i];
        }
        
        return namedValues;
    }
}

QueryRow::QueryRow(const std::vector<std::string>& values, const std::vector<std::string>& columns)
    : values_(values)
    , columns_(columns)
    , namedValues_(buildNamedValues(values, columns)) {
}

const std::string& QueryRow::getValue(const std::string& columnName) const {
    auto it = namedValues_.find(columnName);
    if (it == namedValues_.end()) {
        throw std::out_of_range("列不存在: " + columnName);
    }
    return it->second;
}

const std::string& QueryRow::getValue(size_t index) const {
    if (index >= values_.size()) {
        throw std::out_of_range("索引越界: " + std::to_string(index));
    }
    return values_[index];
}

const std::vector<std::string>& QueryRow::getValues() const {
    return values_;
}

const std::map<std::string, std::string>& QueryRow::getNamedValues() const {
    return namedValues_;
}

bool QueryRow::hasColumn(const std::string& columnName) const {
    return namedValues_.find(columnName) != namedValues_.end();
}

size_t QueryRow::getColumnCount() const {
    return values_.size();
}

std::string QueryRow::toString() const {
    std::stringstream ss;
    ss << "QueryRow{";
    for (size_t i = 0; i < values_.size(); ++i) {
        if (i > 0) {
            ss << ", ";
        }
        ss << columns_[i] << "=" << values_[i];
    }
    ss << "}";
    return ss.str();
}

QueryResult::QueryResult(bool success,
                         const std::string& message,
                         const std::vector<std::string>& columns,
                         const std::vector<std::shared_ptr<QueryRow>>& rows,
                         int totalCount,
                         int64_t executionTime,
                         const std::string& errorCode,
                         bool hasMore)
    : success_(success)
    , message_(message)
    , columns_(columns)
    , rows_(rows)
    , totalCount_(totalCount)
    , executionTime_(executionTime)
    , errorCode_(errorCode)
    , hasMore_(hasMore) {
}

bool QueryResult::isSuccess() const {
    return success_;
}

const std::string& QueryResult::getMessage() const {
    return message_;
}

const std::vector<std::string>& QueryResult::getColumns() const {
    return columns_;
}

const std::vector<std::shared_ptr<QueryRow>>& QueryResult::getRows() const {
    return rows_;
}

int QueryResult::getTotalCount() const {
    return totalCount_;
}

int64_t QueryResult::getExecutionTime() const {
    return executionTime_;
}

const std::string& QueryResult::getErrorCode() const {
    return errorCode_;
}

bool QueryResult::hasMore() const {
    return hasMore_;
}

size_t QueryResult::size() const {
    return rows_.size();
}

bool QueryResult::empty() const {
    return rows_.empty();
}

const QueryRow& QueryResult::operator[](size_t index) const {
    if (index >= rows_.size()) {
        throw std::out_of_range("索引越界: " + std::to_string(index));
    }
    return *rows_[index];
}

const QueryRow& QueryResult::at(size_t index) const {
    return operator[](index);
}

std::string QueryResult::toJson() const {
    std::stringstream json;
    json << "{\n";
    json << "  \"success\": " << (success_ ? "true" : "false") << ",\n";
    json << "  \"message\": \"" << message_ << "\",\n";
    json << "  \"columns\": [";
    
    for (size_t i = 0; i < columns_.size(); ++i) {
        if (i > 0) {
            json << ", ";
        }
        json << "\"" << columns_[i] << "\"";
    }
    json << "],\n";
    
    json << "  \"rows\": [\n";
    for (size_t i = 0; i < rows_.size(); ++i) {
        if (i > 0) {
            json << ",\n";
        }
        json << "    {";
        const auto& row = rows_[i];
        for (size_t j = 0; j < columns_.size(); ++j) {
            if (j > 0) {
                json << ", ";
            }
            json << "\"" << columns_[j] << "\": \"" << row->getValue(j) << "\"";
        }
        json << "}";
    }
    json << "\n  ],\n";
    
    json << "  \"totalCount\": " << totalCount_ << ",\n";
    json << "  \"executionTime\": " << executionTime_ << ",\n";
    json << "  \"errorCode\": \"" << errorCode_ << "\",\n";
    json << "  \"hasMore\": " << (hasMore_ ? "true" : "false") << "\n";
    json << "}";
    
    return json.str();
}

std::string QueryResult::toCsv() const {
    std::stringstream csv;
    
    // 输出列标题
    for (size_t i = 0; i < columns_.size(); ++i) {
        if (i > 0) {
            csv << ",";
        }
        csv << columns_[i];
    }
    csv << "\n";
    
    // 输出数据行
    for (const auto& row : rows_) {
        for (size_t i = 0; i < columns_.size(); ++i) {
            if (i > 0) {
                csv << ",";
            }
            csv << row->getValue(i);
        }
        csv << "\n";
    }
    
    return csv.str();
}

std::string QueryResult::toString() const {
    std::stringstream ss;
    ss << "QueryResult{";
    ss << "success=" << (success_ ? "true" : "false");
    ss << ", message=\"" << message_ << "\"";
    ss << ", columns=" << columns_.size();
    ss << ", rows=" << rows_.size();
    ss << ", totalCount=" << totalCount_;
    ss << ", executionTime=" << executionTime_ << "ms";
    if (!errorCode_.empty()) {
        ss << ", errorCode=\"" << errorCode_ << "\"";
    }
    ss << ", hasMore=" << (hasMore_ ? "true" : "false");
    ss << "}";
    return ss.str();
}

} // namespace kwdb
